import axios from 'axios'

const isPro = process.env.NODE_ENV === 'production' ? 1 : ''
const baseURL = isPro ? 'http://localhost:8888' : 'http://localhost:8888'

function myAxios (axiosConfig, customOptions) {
  const service = axios.create({
    baseURL, // 设置统一的请求前缀
    timeout: 10000 // 设置统一的超时时长
  })

  // 配置化
  customOptions = Object.assign({
    repeat_request_cancel: true, // 默认取消重复的请求
    loading: true // 默认加载loading界面
  }, customOptions)
  // 添加拦截器
  service.interceptors.request.use(
    config => {
      removePending(config)
      customOptions.repeat_request_cancel && addPending(config)
      return config
    },
    error => {
      return Promise.reject(error)
    }
  )
  service.interceptors.response.use(
    response => {
      removePending(response.config)
      return response
    },
    error => {
      error.config && removePending(error.config)
      return Promise.reject(error)
    }
  )

  return service(axiosConfig)
}

// 取消重复请求
/**
 * getPendingKey: 获取(请求时/响应时)的config转为key识别请求
 * addPending:    发送请求前配置config.cancelToken 如果有则用自己,自己没有则new一个,并且将取消改请求的方法存入map中
 * removePending: 删重,每次请求前取消与当前请求重复的请求, 每次请求后删除
 */
const pendingMap = new Map()
// 判断当前请求的接口参数,地址,方式与正在请求中的相同时,请求重复
function getPendingKey (config) {
  let { url, method, params, data } = config
  if (typeof data === 'string') data = JSON.parse(data) // response.config.data (响应配置中的参数) 返回的是字符串,转成jsobj
  return [url, method, JSON.stringify(params), JSON.stringify(data)].join('&')
}
// 存储每个请求的唯一cancel方法,用于取消请求
function addPending (config) {
  const pendingKey = getPendingKey(config)
  config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
    if (!pendingMap.has(pendingKey)) pendingMap.set(pendingKey, cancel)
  })
}
// 删除重复的请求
function removePending (config) {
  const pendingKey = getPendingKey(config)
  if (pendingMap.has(pendingKey)) {
    const cancelToken = pendingMap.get(pendingKey)
    cancelToken(pendingKey)
    pendingMap.delete(pendingKey)
  }
}

export default myAxios
